package main

import (
	"errors"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

// PathExists 判断文件夹是否存在
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// Mkdirs 创建文件夹
func Mkdirs(path string) (bool, error) {
	_path, err := filepath.Abs(path)
	if err == nil {
		path = _path
	}
	exist, _ := PathExists(path)
	if !exist {
		err := os.MkdirAll(path, os.ModePerm)
		if err != nil {
			return false, err
		}
	}
	return true, nil
}

// Mkdir 创建文件夹
func Mkdir(path string) (bool, error) {
	_path, err := filepath.Abs(path)
	if err == nil {
		path = _path
	}
	exist, _ := PathExists(path)
	if !exist {
		err := os.Mkdir(path, os.ModePerm)
		if err != nil {
			return false, err
		}
	}
	return true, nil
}

// FileFilter notes...
type FileFilter interface {
	Accept(IsDir bool, Name string, AbsPath string) bool
}

// FileOrDirFilter 文件夹遍历器 true 存在file返回  false 存在dir返回
type FileOrDirFilter bool

// Accept 遍历查看当前文件夹是否存在文件
func (fd FileOrDirFilter) Accept(IsDir bool, Name string, AbsPath string) bool {
	if bool(fd) {
		return !IsDir
	}
	return IsDir
}

// ListDir 遍历目录
func ListDir(dirPth string, filter FileFilter) (accept bool, err error) {
	if filter == nil {
		return true, errors.New("filter is nil")
	}
	dirPth, err = filepath.Abs(dirPth)
	if err != nil {
		return
	}
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return
	}
	PthSep := string(os.PathSeparator)
	for _, fi := range dir {
		if !filter.Accept(fi.IsDir(), fi.Name(), dirPth+PthSep+fi.Name()) {
			return false, nil
		}
	}
	return true, nil
}

// ListSuffix 遍历当前目录寻找后缀是${suffix}的文件
func ListSuffix(dirPth string, suffix string) ([]string, error) {
	dir, err := ioutil.ReadDir(dirPth)
	if err != nil {
		return nil, err
	}
	var files []string
	PthSep := string(os.PathSeparator)
	suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写

	for _, fi := range dir {
		if fi.IsDir() { // 忽略目录
			continue
		}
		if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) { //匹配文件
			files = append(files, dirPth+PthSep+fi.Name())
		}
	}
	return files, nil
}

// SaveFile 保存文件
func SaveFile(path string, reader io.Reader) error {
	var (
		readN    int
		file     *os.File
		readErr  error
		writeErr error
	)
	file, readErr = os.Create(path)
	if readErr != nil {
		return readErr
	}
	buf := make([]byte, 2048)
	for {
		if readN, readErr = reader.Read(buf); readN > 0 {
			_, writeErr = file.Write(buf[0:readN])
			if writeErr != nil {
				return writeErr
			}
			if readErr == io.EOF {
				return nil
			}
		} else {
			return readErr
		}
	}
}
